/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.byox.drawviewproject.util;

import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * SimpleEventBus 类
 *
 * @since 2021-08-06
 */
public class SimpleEventBus {
    private static SimpleEventBus simpleEventBus;
    private Map<Object, Set<SubscriberBean>> subscriber = new HashMap();
    private String taglog = "LogUtil";
    private HiLogLabel tag = new HiLogLabel(0, 0, taglog);

    /**
     * getSimpleEventBus构造方法
     *
     * @return simpleEventBus对象
     */
    public static synchronized SimpleEventBus getSimpleEventBus() {
        if (simpleEventBus == null) {
            simpleEventBus = new SimpleEventBus();
        }
        return simpleEventBus;
    }

    /**
     * register注册
     *
     * @param object 对象
     */
    public void register(Object object) {
        Class<?> subscriberClass = object.getClass();
        Method[] subscriberMethods = subscriberClass.getMethods();
        synchronized (this) {
            for (int index = 0; index < subscriberMethods.length; index++) {
                if (subscriberMethods[index].getName().startsWith("onSimpleEvent")
                        && subscriberMethods[index].getParameterTypes().length != 0) {
                    String key = subscriberMethods[index].getParameterTypes()[0].getTypeName();
                    SubscriberBean subscriberBean = new SubscriberBean();
                    subscriberBean.subscriber = object;
                    subscriberBean.method = subscriberMethods[index];
                    if (!subscriber.containsKey(key)) {
                        subscriber.put(key, new HashSet<>());
                    }
                    subscriber.get(key).add(subscriberBean);
                }
            }
        }
    }

    /**
     * unRegister反注册
     *
     * @param object 对象
     */
    public void unRegister(Object object) {
        Class<?> subscriberClass = object.getClass();
        Method[] subscriberMethods = subscriberClass.getMethods();
        synchronized (this) {
            for (int index = 0; index < subscriberMethods.length; index++) {
                if (subscriberMethods[index].getName().startsWith("onEvent")) {
                    String key = subscriberMethods[index].getParameterTypes()[0].getTypeName();
                    if (subscriber.containsKey(key)) {
                        subscriber.remove(key);
                    }
                }
            }
        }
    }

    /**
     * post方法
     *
     * @param data 对象数据
     */
    public void post(Object data) {
        try {
            Set<SubscriberBean> subscriberBeans = subscriber.get(data.getClass().getTypeName());
            for (SubscriberBean subscriberBean : subscriberBeans) {
                subscriberBean.method.invoke(subscriberBean.subscriber, data);
            }
        } catch (IllegalAccessException | InvocationTargetException e) {
            HiLog.error(tag,e.getMessage());
        }
    }

    /**
     * SubscriberBean 内部类
     *
     * @since 2021-08-06
     */
    static class SubscriberBean {
        Object subscriber;
        Method method;
    }
}